﻿#region 文件信息

// FileName: SoCafeShop/Sohobloo.SoMcCoffee.Data/EfRepositoryBase.cs
// Author: Sohobloo
// CreateTime: 2013/06/28 20:31
// UpdateTime: 2013/06/30 3:41

#endregion

#region 引用

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Linq.Expressions;
using Sohobloo.SoMcCoffee.Public.Entity;

#endregion

namespace Sohobloo.SoMcCoffee.Data
{
    /// <summary>
    ///     EntityFramework仓储操作基类
    /// </summary>
    /// <typeparam name="TEntity">动态实体类型</typeparam>
    public abstract class EfRepositoryBase<TEntity> : IRepository<TEntity> where TEntity : EntityBase
    {
        #region 属性

        /// <summary>
        ///     获取或设置 EntityFramework的数据仓储上下文
        /// </summary>
        protected IUnitOfWorkContext EfContext
        {
            get
            {
                //if (UnitOfWork is IUnitOfWorkContext)
                //{
                return UnitOfWork as IUnitOfWorkContext;
                //}
                //throw new DataAccessException(string.Format("数据仓储上下文对象类型不正确，应为IUnitOfWorkContext，实际为 {0}", UnitOfWork.GetType().Name));
            }
        }

        /// <summary>
        ///     获取 仓储上下文的实例
        /// </summary>
        [Import]
        public IUnitOfWork UnitOfWork { get; set; }

        /// <summary>
        ///     获取 当前实体的查询数据集
        /// </summary>
        public virtual IQueryable<TEntity> Entities
        {
            get { return EfContext.Set<TEntity>(); }
        }

        #endregion 属性

        #region 方法

        /// <summary>
        ///     删除指定编号的记录
        /// </summary>
        /// <param name="key"> 实体记录编号 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(Guid key, bool isSave = true)
        {
            //PublicHelper.CheckArgument(id, "id");
            var entity = EfContext.Set<TEntity>().Find(key);
            return entity != null ? Delete(entity, isSave) : 0;
        }

        /// <summary>
        ///     删除实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(TEntity entity, bool isSave = true)
        {
            //PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterDeleted(entity);
            return isSave ? EfContext.Commit() : 0;
        }

        /// <summary>
        ///     删除实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(IEnumerable<TEntity> entities, bool isSave = true)
        {
            //PublicHelper.CheckArgument(entities, "entities");
            EfContext.RegisterDeleted(entities);
            return isSave ? EfContext.Commit() : 0;
        }

        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true)
        {
            //PublicHelper.CheckArgument(predicate, "predicate");
            var entities = EfContext.Set<TEntity>().Where(predicate).ToList();
            return entities.Count > 0 ? Delete(entities, isSave) : 0;
        }

        public virtual TEntity GetByKey(Guid key)
        {
            return EfContext.Set<TEntity>().Find(key);
        }

        /// <summary>
        ///     插入实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Insert(TEntity entity, bool isSave = true)
        {
            //PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterNew(entity);
            return isSave ? EfContext.Commit() : 0;
        }

        /// <summary>
        ///     批量插入实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Insert(IEnumerable<TEntity> entities, bool isSave = true)
        {
            //PublicHelper.CheckArgument(entities, "entities");
            EfContext.RegisterNew(entities);
            return isSave ? EfContext.Commit() : 0;
        }

        /// <summary>
        ///     更新实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Update(TEntity entity, bool isSave = true)
        {
            //PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterModified(entity);
            return isSave ? EfContext.Commit() : 0;
        }

        #endregion 方法
    }
}